﻿using System;
using System.Threading;


namespace Jenvin.Library.Threading
{
    /// <summary>
    /// 任务分配器，负责分配任务队列中和任务。结线程池，执行
    /// </summary>
    internal class TaskDispatcher
    {
        private static TaskDispatcher m_instance = new TaskDispatcher();

        public static TaskDispatcher Instance
        {
            get
            {
                return m_instance;
            }
        }

        public void ReadyToExecute(TaskActor taskQ)
        {
            if (taskQ.Context.Exited) return;
            
            int status = Interlocked.CompareExchange(
                ref taskQ.Context.m_status,
                TaskContext.EXECUTING,
                TaskContext.WAITING);

            if (status == TaskContext.WAITING)
            {
                ThreadPool.QueueUserWorkItem(this.Execute, taskQ);
            }
        }

        private void Execute(object o)
        {
            TaskActor taskQ = (TaskActor)o;
            taskQ.Execute();

            if (taskQ.Context.Exited)
            {
                Thread.VolatileWrite(
                    ref taskQ.Context.m_status,
                    TaskContext.EXITED);
                taskQ.Context.m_waitForExit.Set();
            }
            else
            {
                Thread.VolatileWrite(
                    ref taskQ.Context.m_status,
                    TaskContext.WAITING);

                if (taskQ.Context.TaskCount > 0)
                {
                    this.ReadyToExecute(taskQ);
                }
            }
        }
    }
}
